package cn.wolfcode.luowowo.web.controller;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.search.domain.DestinationEs;
import cn.wolfcode.luowowo.search.domain.StrategyEs;
import cn.wolfcode.luowowo.search.domain.TravelEs;
import cn.wolfcode.luowowo.search.domain.UserInfoEs;
import cn.wolfcode.luowowo.search.query.SearchQueryObject;
import cn.wolfcode.luowowo.search.service.ISearchService;
import cn.wolfcode.luowowo.search.vo.SearchResultVo;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.service.ITravelsService;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.JsonResult;
import cn.wolfcode.luowowo.util.ParamMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;

@RestController
public class SearchController {
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IStrategyService strategyService;
    @Autowired
    private ITravelsService travelsService;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private ISearchService searchService;
    @GetMapping("/q")
    public Object search(SearchQueryObject qo) throws UnsupportedEncodingException {

        String decode = URLDecoder.decode(qo.getKeyword(), "Utf-8");
        qo.setKeyword(decode);

        switch (qo.getType()){
            case  SearchQueryObject.TYPE_DESTINATION ://查询目的地
                //目的地
                return searchDest(qo);
            case  SearchQueryObject.TYPE_STRATEGY ://查询攻略
                //攻略
                return searchStrategy(qo);
            case  SearchQueryObject.TYPE_TRAVEL ://查询游记
                //游记
                return searchTravel(qo);
            case  SearchQueryObject.TYPE_USERINFO ://查询用户
                //用户
                return searchUser(qo);
            default:
                //全部
                return searchAll(qo);//查询全部
        }
    }

    //查询目的地
    private Object searchDest(SearchQueryObject qo){
        //先进行查询,看看是否存在此目的地
        Destination destination = destinationService.queryByName(qo.getKeyword());
        //新建一个结果数据对象
        SearchResultVo data = new SearchResultVo();
        //如果目的地存在
        if(destination != null){
            //2:存在: 查询指定目的地下的攻略, 游记, 用户
            List<Strategy> sts = strategyService.getByDestName(qo.getKeyword());
            List<Travel> ts = travelsService.getByDestName(qo.getKeyword());
            List<UserInfo> us = userInfoService.getByCity(qo.getKeyword());
            data.setTotal(sts.size() + us.size() + ts.size() + 0L);
            data.setUsers(us);
            data.setStrategys(sts);
            data.setTravels(ts);
        }
        //3:不存在: 提示不存在
        return JsonResult.success(new ParamMap().put("result", data).put("dest", destination).put("qo", qo));
    }

    //查询攻略
    private Object searchStrategy(SearchQueryObject qo){
        return JsonResult.success(new ParamMap().put("page", this.getStrategyPage(qo)).put("qo", qo));
    }

    //查询游记
    private Object searchTravel(SearchQueryObject qo){
        return JsonResult.success(new ParamMap().put("page", this.getTravelPage(qo)).put("qo", qo));
    }

    //查询用户
    private Object searchUser(SearchQueryObject qo){
        return JsonResult.success(new ParamMap().put("page", this.getUserInfoPage(qo)).put("qo", qo));
    }

    //查询全部
    private Object searchAll(SearchQueryObject qo){
        Page<Strategy> sts = this.getStrategyPage(qo);
        Page<Travel> ts = this.getTravelPage(qo);
        Page<UserInfo> us = this.getUserInfoPage(qo);
        Page<Destination> ds = this.getDestinationPage(qo);

        SearchResultVo vo = new SearchResultVo();

        vo.setDests(ds.getContent());
        vo.setStrategys(sts.getContent());
        vo.setTravels(ts.getContent());
        vo.setUsers(us.getContent());

        vo.setTotal(sts.getTotalElements() + ts.getNumberOfElements() + us.getTotalElements() + ds.getTotalElements());

        return JsonResult.success(new ParamMap().put("result", vo).put("qo", qo));
    }
    private Page<Destination> getDestinationPage(SearchQueryObject qo){
        Page<Destination> page = searchService.searchWithHighlight(DestinationEs.INDEX_NAME, DestinationEs.TYPE_NAME, Destination.class, qo,
                "name", "info");
        return page;
    }
    private Page<Strategy> getStrategyPage(SearchQueryObject qo){
        Page<Strategy> page = searchService.searchWithHighlight(
                StrategyEs.INDEX_NAME, StrategyEs.TYPE_NAME,
                Strategy.class, qo,
                "title", "subTitle", "summary");
        return page;
    }
    private Page<UserInfo> getUserInfoPage(SearchQueryObject qo){
        Page<UserInfo> page = searchService.searchWithHighlight(
                UserInfoEs.INDEX_NAME, UserInfoEs.TYPE_NAME,
                UserInfo.class, qo,
                "city", "info");
        return page;
    }
    private Page<Travel> getTravelPage(SearchQueryObject qo){
        Page<Travel> page = searchService.searchWithHighlight(
                TravelEs.INDEX_NAME, TravelEs.TYPE_NAME,
                Travel.class, qo,
                "title", "summary");
        return page;
    }
}
